package com.ww.microrpc.netty.handler;

import com.ww.microrpc.netty.Constant;
import com.ww.microrpc.netty.protocol.ErrorMessage;
import com.ww.microrpc.netty.protocol.Message;
import com.ww.microrpc.netty.serializer.Serializer;
import com.ww.microrpc.netty.serializer.SerializerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * RPC Decoder （ Byte to RpcMessage )
 *
 * @author ww
 */
public class RpcDecoderHandler extends ByteToMessageDecoder {
    private static final Logger logger = LoggerFactory.getLogger(RpcDecoderHandler.class);

    @Override
    public final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int length = in.readInt();
        int messageType = in.readByte();
        int serializerType = in.readByte();
        int version = in.readByte();
        int version2 = in.readByte();
        int requestId = in.readInt();
        byte[] data = new byte[length];
        in.readBytes(data);
        Serializer serializer = SerializerFactory.create(serializerType);
        Class<? extends Message> clazz = Constant.getMessageClass(messageType);

        try {
            Message obj = serializer.deserialize(data, clazz);
            out.add(obj);
        } catch (Exception ex) {
            logger.error("decode error: ", ex);
            ErrorMessage error = new ErrorMessage();
            error.setRequestId(requestId);
            error.setErrorMessage("decode error: " + ex.getMessage());
            out.add(error);
        }
    }
}
